import { CacheEnum } from "@/enum/cacheEnum";
import router from "@/router";
import store from "@/utils/store";
import axios from "axios";
import type { AxiosRequestConfig, AxiosResponse } from "axios";
import QS from "qs";

export class Axios {
  private instance;
  constructor(config: AxiosRequestConfig) {
    this.instance = axios.create(config);

    this.interceptors();
  }

  public async fileRequest(config: AxiosRequestConfig) {
    return new Promise(async (resolve, rejects) => {
      try {
        const response = await this.instance.request(config);
        resolve(response);
      } catch (error) {
        rejects(error);
      }
    }) as Promise<AxiosResponse<Blob>>;
  }

  public async request<T, D = ResponseResult<T>>(config: AxiosRequestConfig) {
    return new Promise(async (resolve, rejects) => {
      try {
        const response = await this.instance.request<D>(config);
        resolve(response.data);
      } catch (error) {
        rejects(error);
      }
    }) as Promise<D>;
  }
  private interceptors() {
    this.interceptorsRequest();
    this.interceptorsResponse();
  }

  private interceptorsRequest() {
    this.instance.interceptors.request.use(
      (config) => {
        // 在发送请求之前做些什么
        //防止未登录无法获取token
        config.headers.Authorization =
          "Bearer" + store.get(CacheEnum.TOKEN_NAME)?.token;
        //登录后每次发送请求携带部门编码，进而判断用户权限
        if (config.method === "post") {
          let deptCode = {
            deptCode: store.get(CacheEnum.TOKEN_NAME)?.userInfo.DeptCode,
          };
          config.data = Object.assign(deptCode, config.data);
          config.data = QS.stringify(config.data);
        }
        return config;
      },
      (error) => {
        // 对请求错误做些什么
        return Promise.reject(error);
      }
    );
  }
  private interceptorsResponse() {
    // 添加响应拦截器
    this.instance.interceptors.response.use(
      (response) => {
        // 2xx 范围内的状态码都会触发该函数。
        // 对响应数据做点什么
        return response;
      },
      (error) => {
        // 超出 2xx 范围的状态码都会触发该函数。
        // 对响应错误做点什么
        switch (error.response.status) {
          case 401:
            store.remove(CacheEnum.TOKEN_NAME);
            router.push({ name: "login" });
            break;
        }
        return Promise.reject(error);
      }
    );
  }
}
